home *** CD-ROM | disk | FTP | other *** search
- ;History:26,1
- page ,132
-
- comment /
-
- Porting EMACS and Percival to MS-DOS computers other than the Z-100:
-
- This entire file (Z-100.ASM) needs to be re-written, since it contains
- all the Z-100 dependencies. The following conventions must be maintained:
- 1) Never leave this module with DF=1.
- 2) Never destroy ES.
- 3) Never MOV AX,DATA, always use the copy in the appropriate segment register.
- 4) Return NC if a routine succeeds, or fulfills its goals.
-
- /
- .xlist
- include memory.def
-
-
- data segment byte public
-
- public max_screen_line
- max_screen_line db 22 ;number of last text row on screen.
-
-
- public scan_lines_per_char
- scan_lines_per_char db 8
-
-
- key_names label byte
- db ',','Comma',0
- db '(','LPar',0
- db ')','RPar',0
- db 7fh,'Delete',0
-
- db -1,'Timeout',0
- db -2,'Left Down',0 ;mouse button key names.
- db -3,'Right Down',0
- db -4,'Left Up',0
- db -5,'Right Up',0
- db -6,'Middle Down',0
- db -7,'Middle Up',0
-
- db 0
-
-
- key_others label byte
- db 14,'Back Space',0
- db 15,'Tab',0
- db 28,'Return',0
- db 1,'Escape',0
-
- db 0
-
-
- key_table label byte
- db 3,'C-@',0
-
- db 15,'Back Space',0
-
- db 71,'Home',0
- db 79,'End',0
- db 73,'Pg Up',0
- db 81,'Pg Dn',0
- db 75,'Left Arrow',0
- db 77,'Right Arrow',0
- db 72,'Up Arrow',0
- db 80,'Down Arrow',0
- db 82,'Ins',0
- db 83,'Del',0
-
- db 59,'F1',0
- db 60,'F2',0
- db 61,'F3',0
- db 62,'F4',0
- db 63,'F5',0
- db 64,'F6',0
- db 65,'F7',0
- db 66,'F8',0
- db 67,'F9',0
- db 68,'F10',0
-
- db 84,'F1',0
- db 85,'F2',0
- db 86,'F3',0
- db 87,'F4',0
- db 88,'F5',0
- db 89,'F6',0
- db 90,'F7',0
- db 91,'F8',0
- db 92,'F9',0
- db 93,'F10',0
-
- db 94,'F1',0
- db 95,'F2',0
- db 96,'F3',0
- db 97,'F4',0
- db 98,'F5',0
- db 99,'F6',0
- db 100,'F7',0
- db 101,'F8',0
- db 102,'F9',0
- db 103,'F10',0
-
- db 104,'F1',0
- db 105,'F2',0
- db 106,'F3',0
- db 107,'F4',0
- db 108,'F5',0
- db 109,'F6',0
- db 110,'F7',0
- db 111,'F8',0
- db 112,'F9',0
- db 113,'F10',0
-
- db 119,'Home',0
- db 117,'End',0
- db 132,'Pg Up',0
- db 118,'Pg Dn',0
- db 115,'Left Arrow',0
- db 116,'Right Arrow',0
- db 160,'Up Arrow',0
- db 164,'Down Arrow',0
- db 165,'Ins',0
- db 166,'Del',0
-
- db 129,'0',0 ;alt top row
- db 120,'1',0
- db 121,'2',0
- db 122,'3',0
- db 123,'4',0
- db 124,'5',0
- db 125,'6',0
- db 126,'7',0
- db 127,'8',0
- db 128,'9',0
- db 130,'-',0
- db 131,'=',0
-
- db 16,'q',0 ;alt second row
- db 17,'w',0
- db 18,'e',0
- db 19,'r',0
- db 20,'t',0
- db 21,'y',0
- db 22,'u',0
- db 23,'i',0
- db 24,'o',0
- db 25,'p',0
-
- db 30,'a',0 ;alt third row
- db 31,'s',0
- db 32,'d',0
- db 33,'f',0
- db 34,'g',0
- db 35,'h',0
- db 36,'j',0
- db 37,'k',0
- db 38,'l',0
-
- db 44,'z',0 ;alt fourth row
- db 45,'x',0
- db 46,'c',0
- db 47,'v',0
- db 48,'b',0
- db 49,'n',0
- db 50,'m',0
-
- db 0,'Unknown',0
-
-
- one_key_string db ?,0
-
- ctrl_flag equ 1
- left_flag equ 2
- right_flag equ 4
- alt_flag equ 8
- shift_flags db ?
-
-
- key_buffer label byte ;this is where we put the ASCII
- db 26 dup(?) ; representation of the key.
-
-
- extrn inversing: word ;if we're inverse videoing.
-
- public color
- color db 07h ;xbbbxfff bbb=background, fff=fore.
-
- font_8_table label byte
- db 007h ;visi space
- db 004h ;visi tab
- db ? ;del
- db ? ;eof
- db ? ;visi newline
- db 01ah ;right arrow
- db ? ;random char.
- db 01fh ;visible newline.
-
- ;a character must be chosen which causes the idling string to be reloaded.
- ; this one is ctrl-prtsc.
- public breakchar
- breakchar dw 114*256 + 0
-
- data ends
-
-
- code segment byte public
- assume cs:code, ds:data, es:nothing
- ;all of the code in this segment is called with the above assumes.
-
-
- their_keybd dd ? ;-> their keyboard handler.
-
- public init_entry
- init_entry:
- mov ax,0*256 + 3 ;25x80 color.
- int 10h
-
- push es
- mov ax,3509h
- int 21h
- mov word ptr their_keybd+0,bx
- mov word ptr their_keybd+2,es
- pop es
-
- push ds
- mov ax,cs
- mov ds,ax
- mov dx,offset our_keybd
- mov ax,2509h
- int 21h
- pop ds
-
- ret
-
-
- public uninit_exit
- uninit_exit:
- ;called when exiting. May destroy any but seg-regs.
- mov dh,0 ;put the cursor on the last scrollable line.
- mov dl,max_screen_line
- inc dl
- call position_cursor
-
- push ds
- lds dx,their_keybd
- mov ax,2509h
- int 21h
- pop ds
-
- ret
-
-
- bios_seg segment at 40h
- org 1ah
- buffer_head dw ?
- buffer_tail dw ?
- kb_buffer dw 16 dup(?)
- kb_buffer_end label word
- bios_seg ends
-
-
- our_keybd:
- push ax
- push bx
- push ds
- mov ax,bios_seg
- mov ds,ax
- assume ds:bios_seg
- in al,60h ;get the current keycode.
- mov ah,al ;remember the keycode.
- and al,7fh ;forget the shift.
- cmp al,1dh ;ctrl
- je our_keybd_2
- cmp al,2ah ;left shift
- je our_keybd_2
- cmp al,36h ;right shift
- je our_keybd_2
- cmp al,38h ;alt
- jne our_keybd_1
- our_keybd_2:
- mov al,80h ;make a 80h with special scan codes.
- mov bx,buffer_tail
- add bx,2
- cmp bx,offset kb_buffer_end
- jne our_keybd_3
- mov bx,offset kb_buffer
- our_keybd_3:
- cmp bx,buffer_head ;any room?
- je our_keybd_1 ; no.
- xchg buffer_tail,bx ;save the new, get the old.
- mov [bx],ax ;store the key at the old ptr.
- our_keybd_1:
- pop ds
- pop bx
- pop ax
- jmp their_keybd
-
- assume ds:data
-
-
- public check_for_key
- check_for_key:
- ;return zr,ax=0 if no key is waiting.
- ;return nz,ax=key if a key is waiting, but don't input the key yet.
- mov ah,1 ;check for a key.
- int 16h
- jne check_for_key_1 ;go if we got a key.
- mov ax,0 ;return ax=0 if we didn't.
- ret
- check_for_key_1:
- call detect_shifts
- jne check_for_key_2
- mov ah,0 ;must have been a shift key -
- int 16h ; get rid of it.
- xor ax,ax
- check_for_key_2:
- ret
-
-
- public get_key_value
- get_key_value:
- ;exit with ax=keycode.
- mov ah,0
- int 16h
- call detect_shifts ;remove shift bytes from the buffer.
- je get_key_value
- ret
-
-
- detect_shifts:
- ;enter with ax=keycode.
- ;exit with zr,ax=0 if it was a shift code.
- ;exit with nz,ax=key if a real key.
- cmp al,80h ;our special code?
- jne detect_shifts_1 ;no - must be a real key.
- detect_shifts_5:
- mov al,ctrl_flag
- cmp ah,1dh ;ctrl down
- je detect_shifts_6
- cmp ah,1dh+80h ;ctrl up
- je detect_shifts_6
- mov al,left_flag
- cmp ah,2ah ;left shift down
- je detect_shifts_6
- cmp ah,2ah+80h ;left shift up
- je detect_shifts_6
- mov al,right_flag
- cmp ah,36h ;right shift down
- je detect_shifts_6
- cmp ah,36h+80h ;right shift up
- je detect_shifts_6
- mov al,alt_flag
- cmp ah,38h ;alt down
- je detect_shifts_6
- cmp ah,38h+80h ;alt up
- jne detect_shifts_7 ;unknown, but not a key.
- detect_shifts_6:
- or shift_flags,al ;assume down
- or ah,ah ;down or up?
- jns detect_shifts_7 ;go if down
- not al ;up - make inverse flag.
- and shift_flags,al ; and turn the bit off.
- detect_shifts_7:
- xor ax,ax ;return zero.
- detect_shifts_1:
- ret
-
-
- public decode_key
- decode_key:
- ;enter with ax=key value.
- ;exit with si,cx -> the key's name in ASCII.
- mov di,offset key_buffer
-
- or al,al ;extended function key?
- je decode_key_5
-
- push ax
- mov si,offset key_others
- call decode_search ;search for the scan code names.
- pop ax
- jne decode_key_1
-
- mov ah,al
- mov si,offset key_names
- call decode_search ;search for the literal names.
- jne decode_key_7 ;copy it in, but don't do shifts.
- mov al,ah
-
- cmp al,' ' ;control char?
- jae decode_key_6 ;no
- add al,'@' ;yes - convert into letter.
- mov one_key_string,al
- mov si,offset one_key_string
- jmp decode_key_1
- decode_key_6:
- mov one_key_string,al
- mov si,offset one_key_string
- cmp al,' '
- je decode_key_1 ;interpret shift for space bar.
- call decode_meta ;don't interpret shift key for printables.
- call decode_ctrl
- jmp decode_key_7
-
- decode_key_5:
- mov si,offset key_table ;search for the extended functions.
- call decode_search
- decode_key_1:
- call decode_meta
- call decode_ctrl
- call decode_shift
- decode_key_7:
- lodsb ;copy to the next null.
- stosb
- or al,al
- jne decode_key_7
- dec di ;don't include the null.
- mov si,offset key_buffer
- mov cx,di
- sub cx,si
- ret
-
-
- decode_ctrl:
- test shift_flags,ctrl_flag
- je decode_ctrl_1
- mov ax,'C' + '-'*256
- stosw
- decode_ctrl_1:
- ret
-
-
- decode_shift:
- test shift_flags,left_flag + right_flag
- je decode_shift_1
- mov ax,'S' + '-'*256
- stosw
- decode_shift_1:
- ret
-
- decode_meta:
- test shift_flags,alt_flag
- je decode_meta_1
- mov ax,'M' + '-'*256
- stosw
- decode_meta_1:
- ret
-
-
- decode_search:
- ;enter with ah=key to search for, si->table.
- ;exit with al=key, nz if found, al=0, zr if not found.
- lodsb
- or al,al ;end of table?
- je decode_search_2 ;yes - try shifted values.
- cmp al,ah ;is this the key?
- je decode_search_2 ;yes.
- decode_search_1:
- lodsb ;skip to the next null.
- or al,al
- jne decode_search_1
- jmp decode_search
- decode_search_2:
- or al,al
- ret
-
-
- public ring_the_bell
- ring_the_bell:
- mov bx,6779
- call beep
- ret
-
-
- ;Beep procedure count values
- ;---------------------------
- ;To generate a given freqency note out of the speaker with the Beep procedure
- ;on the PC using Channel 2 of the 8253 timer, the channel 2 count register
- ;must be loaded with a value such that the 8253 input clock frequency
- ;(1.19318 MHz) divided by the count figure equals the audio frequency.
- ;enter with bx=count figure for frequency to be generated.
- beep:
- mov al,0b6h ; Channel 2, LSB then MSB, Square Wave, Binary
- out 43h,al ; Program 8253 command register
- mov ax,bx ; Get the frequency to be generated
- out 42h,al ; Load Channel 2 count register LSB
- mov al,ah
- out 42h,al ; Load Channel 2 count register MSB
- in al,61h ; Read settings from 8255 PPI I/O Port "PB"
- mov ah,al ; Save original settings in AH
- or al,3 ; Enable Timer Channel 2 & Speaker data
- out 61h,al ; program the 8255 with new setting-speaker on
- sub cx,cx ; Sneaky way to put 0FFFFH into CX when
- wait2: loop wait2 ; LOOP is first executed
- mov al,ah ; Get original 8255 Port "PB" settings
- out 61h,al ; Reset port to original values-speaker off
- ret
-
-
- code ends
-
- code segment byte public
- assume cs:code, ds:nothing, es:data
- ;all of the code in this segment is called with the above assumes.
-
- public position_cursor
- position_cursor:
- ;enter with dh=col (0...80), dl=row (0..max_screen_line)
- ;exit with cursor set to that position.
- push si
- push di
- push bp
- push bx
- xchg dh,dl
- mov bh,0
- mov ah,2 ;set cursor position
- int 10h
- cld
- xchg dh,dl
- pop bx
- pop bp
- pop di
- pop si
- ret
-
-
- public move_line
- move_line:
- ;enter with dl=source row, al=destination row.
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push bp
- push ds
- push es
-
- push ax ;compute the source byte.
- mov al,80*2
- mul dl
- mov si,ax
- pop ax
-
- mov ah,80*2 ;compute the destination byte.
- mul ah
- mov di,ax
-
- call get_video_seg ;get the video card plane.
- mov ds,ax
-
- mov cx,80 ;move the line.
- rep movsw
-
- pop es
- pop ds
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
-
-
- public clear_to_eol
- clear_to_eol:
- ;enter with dl=current row, dh=current column.
- push bx
- mov bl,80
- call clear_count
- pop bx
- ret
-
-
- public clear_count
- clear_count:
- ;enter with dl=current row, dh=current column, bl=column to clear to.
- push ax
- push bx
- push cx
- push si
- push di
- push bp
- push es
- clear_count_0:
- cmp dh,bl ;already past it?
- jae clear_count_1 ;yes.
-
- mov ah,color
- mov al,' ' ;clear to the background color.
- push ax
- call get_video_ptr
- pop ax
-
- mov cl,bl ;compute the number of chars to clear.
- sub cl,dh
- mov ch,0
- rep stosw
-
- clear_count_1:
- pop es
- pop bp
- pop di
- pop si
- pop cx
- pop bx
- pop ax
- ret
-
-
- get_video_ptr:
- ;enter with dl=current row, dh=current column.
- ;return with es:di->character position.
- mov al,80 ;compute the offset of the char.
- mul dl
- add al,dh
- adc ah,0
- shl ax,1
- mov di,ax
- get_video_seg:
- ;return with es,ax=video segment.
- xor ax,ax
- mov es,ax
- mov ax,0b000h
- cmp byte ptr es:[449h],7 ;b/w card?
- je get_video_seg_1 ;yes - we have the segment already.
- mov ax,0b800h ;no - segment at b800h.
- get_video_seg_1:
- mov es,ax
- ret
-
-
- public xychrout
- xychrout:
- ;enter with dh=col, dl=row, al=character to print, ah=font to print it in.
- push ax ;save everything that we might need.
- push bx
- push cx
- push dx
- push di
- push si
- push es
- push ds
- mov bx,es
- mov ds,bx
- cmp dh,80 ;past the right margin?
- jae xychrout_3 ;yes - don't print.
- cmp ah,0 ;font zero?
- jne xychrout_5 ;no - print specially.
- mov ah,color ;assume no inverse video
- cmp al,20h ;print control chars specially.
- jb xychrout_control
- cmp al,0ffh ;print 255 specially
- je xychrout_del
- jmp short xychrout_1
- xychrout_control:
- mov ah,color
- or ah,10h ;bold chars.
- add al,'@'
- jmp short xychrout_1
- xychrout_del:
- mov ah,color
- or ah,10h
- mov al,7fh ;bold del.
- jmp short xychrout_1
- xychrout_5:
- mov ah,color
- mov bx,offset font_8_table
- sub al,4dh ;first character in font 8.
- xlat
- xychrout_1:
- mov bx,inversing ;set the inverse video flag.
- and bl,77h ;strip out just the color.
- xor ah,bl ;now flip the colors (if desired).
- push ax
- call get_video_ptr
- pop ax
- stosw
- xychrout_3:
- pop ds
- pop es
- pop si
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- ret
-
-
- public hardware_roll_down
- hardware_roll_down:
- ;exit: if this machine is capable of hardware roll, do it and exit with cy=0,
- ; otherwise, exit with cy=1. The hardware roll must leave the last line
- ; on the screen as the last line.
- ;preserve bx.
- if 0
- mov dl,24 ;move the 25th line up.
- mov al,23
- call move_line
-
- push bx
- mov cx,0*256 + 0
- mov dx,24*256 + 79
- mov bh,07h
- mov ax,7*256 + 1
- int 10h
- pop bx
- clc
- else
- stc
- endif
- ret
-
-
- public hardware_roll_up
- hardware_roll_up:
- ;exit: if this machine is capable of hardware roll, do it and exit with cy=0,
- ; otherwise, exit with cy=1. The hardware roll must leave the last line
- ; on the screen as the last line.
- ;preserve bx.
- if 0
- push bx
- mov cx,0*256 + 0
- mov dx,24*256 + 79
- mov bh,07h
- mov ax,6*256 + 1
- int 10h
- pop bx
- mov dl,23 ;now move the 25th line back down.
- mov al,24
- call move_line
- clc
- else
- stc
- endif
- ret
-
-
- public block_cursor
- block_cursor:
- mov ah,1
- mov cx,0*256 + 7
- int 10h
- ret
-
-
- public underscore_cursor
- underscore_cursor:
- mov ah,1
- mov cx,6*256 + 7
- int 10h
- ret
-
-
- public set_screen_color
- set_screen_color:
- ;enter with al=fore color, ah=back color
- shl ah,1
- shl ah,1
- shl ah,1
- shl ah,1
- or al,ah
- mov color,al
- ret
-
-
- code ends
-
- end